package com.fishingwithme.android.utils

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import kotlin.math.ceil

/**
 * 优化后的图片处理工具类
 * 解决压缩效果不理想问题，采用动态质量调整和精确采样策略
 */
object ImageUtils {

    // 目标压缩参数（可根据需求调整）
    private const val TARGET_MAX_SIZE_KB = 500 // 目标最大文件大小(KB)
    private const val MIN_COMPRESS_QUALITY = 30 // 最小压缩质量
    private const val MAX_COMPRESS_QUALITY = 90 // 最大压缩质量
    private const val MAX_WIDTH = 1200 // 最大宽度
    private const val MAX_HEIGHT = 1200 // 最大高度

    /**
     * 压缩图片文件（优化版）
     * 结合尺寸压缩和质量压缩，动态调整参数以达到理想效果
     */
    fun compressImage(context: Context, uri: Uri): File? {
        return try {
            // 1. 获取原始图片信息（尺寸、格式）
            val (originalWidth, originalHeight, mimeType) = getImageInfo(context, uri)
                ?: return null

            // 2. 计算合适的采样率
            val sampleSize = calculateOptimalSampleSize(
                originalWidth, originalHeight,
                MAX_WIDTH, MAX_HEIGHT
            )

            // 3. 解码并缩小图片
            val scaledBitmap = decodeScaledBitmap(context, uri, sampleSize)
                ?: return null

            // 4. 处理图片方向
            val rotatedBitmap = rotateImageIfRequired(context, scaledBitmap, uri)

            // 5. 动态质量压缩
            val compressedBitmap = compressWithDynamicQuality(
                rotatedBitmap,
                mimeType,
                TARGET_MAX_SIZE_KB
            )

            // 6. 保存压缩后的图片
            val outputFile = saveCompressedImage(
                context,
                compressedBitmap,
                mimeType
            )

            // 释放资源
            if (scaledBitmap != rotatedBitmap) scaledBitmap.recycle()
            if (rotatedBitmap != compressedBitmap) rotatedBitmap.recycle()
            compressedBitmap.recycle()

            outputFile
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    /**
     * 获取图片基本信息（尺寸、MIME类型）
     */
    private fun getImageInfo(context: Context, uri: Uri): Triple<Int, Int, String?>? {
        return try {
            context.contentResolver.openInputStream(uri)?.use { inputStream ->
                val options = BitmapFactory.Options().apply {
                    inJustDecodeBounds = true
                }
                BitmapFactory.decodeStream(inputStream, null, options)

                Triple(
                    options.outWidth,
                    options.outHeight,
                    context.contentResolver.getType(uri)
                )
            }
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }
    }

    /**
     * 计算更精确的采样率（不局限于2的幂）
     */
    private fun calculateOptimalSampleSize(
        originalWidth: Int,
        originalHeight: Int,
        targetWidth: Int,
        targetHeight: Int
    ): Int {
        var sampleSize = 1

        // 只在原图尺寸超过目标尺寸时进行缩小
        if (originalWidth > targetWidth || originalHeight > targetHeight) {
            val widthRatio = originalWidth.toFloat() / targetWidth
            val heightRatio = originalHeight.toFloat() / targetHeight

            // 取较大的比例作为基准，确保缩小后的图片不超过目标尺寸
            val ratio = maxOf(widthRatio, heightRatio).toDouble()

            // 采样率向上取整，避免图片过大
            sampleSize = ceil(ratio).toInt()

            // 限制最大采样率，避免图片过小
            if (sampleSize > 8) sampleSize = 8
        }
        return sampleSize
    }

    /**
     * 根据采样率解码图片
     */
    private fun decodeScaledBitmap(
        context: Context,
        uri: Uri,
        sampleSize: Int
    ): Bitmap? {
        return try {
            // 重新获取输入流（因为之前的流可能已关闭）
            val inputStream = context.contentResolver.openInputStream(uri)
            inputStream?.use { stream ->
                val options = BitmapFactory.Options().apply {
                    inSampleSize = sampleSize
                    inPreferredConfig = Bitmap.Config.RGB_565 // 减少内存占用
                }
                BitmapFactory.decodeStream(stream, null, options)
            }
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }
    }

    /**
     * 动态调整压缩质量，确保文件大小接近目标值
     */
    private fun compressWithDynamicQuality(
        bitmap: Bitmap,
        mimeType: String?,
        targetMaxSizeKb: Int
    ): Bitmap {
        // 初始质量（根据图片类型调整）
        var quality = when {
            mimeType?.contains("png", ignoreCase = true) == true -> 90
            else -> 70
        }

        // 字节数组输出流，用于计算压缩后的大小
        val outputStream = ByteArrayOutputStream()
        val compressFormat = getCompressFormat(mimeType)

        // 循环调整质量直到满足大小要求或达到最小质量
        while (true) {
            outputStream.reset()
            bitmap.compress(compressFormat, quality, outputStream)
            val sizeKb = outputStream.size() / 1024

            // 满足条件则退出循环
            if (sizeKb <= targetMaxSizeKb || quality <= MIN_COMPRESS_QUALITY) {
                break
            }

            // 每次降低5%质量
            quality -= 5
        }

        // 将优化后的字节数组转换为Bitmap
        val compressedData = outputStream.toByteArray()
        return BitmapFactory.decodeByteArray(compressedData, 0, compressedData.size)
    }

    /**
     * 根据MIME类型获取合适的压缩格式
     */
    private fun getCompressFormat(mimeType: String?): Bitmap.CompressFormat {
        return when {
            mimeType?.contains("png", ignoreCase = true) == true ->
                Bitmap.CompressFormat.PNG // PNG保留透明通道
            mimeType?.contains("webp", ignoreCase = true) == true &&
                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ->
                Bitmap.CompressFormat.WEBP_LOSSY // Android 11+ 支持WebP
            else ->
                Bitmap.CompressFormat.JPEG
        }
    }

    /**
     * 保存压缩后的图片到文件
     */
    private fun saveCompressedImage(
        context: Context,
        bitmap: Bitmap,
        mimeType: String?
    ): File {
        val extension = when {
            mimeType?.contains("png", ignoreCase = true) == true -> "png"
            mimeType?.contains("webp", ignoreCase = true) == true -> "webp"
            else -> "jpg"
        }

        val outputFile = File(
            context.cacheDir,
            "compressed_${System.currentTimeMillis()}.${extension}"
        )

        FileOutputStream(outputFile).use { fos ->
            bitmap.compress(getCompressFormat(mimeType), MAX_COMPRESS_QUALITY, fos)
            fos.flush()
        }

        return outputFile
    }

    /**
     * 根据EXIF信息旋转图片（支持更多方向）
     */
    private fun rotateImageIfRequired(context: Context, bitmap: Bitmap, uri: Uri): Bitmap {
        return try {
            context.contentResolver.openInputStream(uri)?.use { inputStream ->
                val exif = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    ExifInterface(inputStream)
                } else {
                    // 兼容旧版本
                    @Suppress("DEPRECATION")
                    ExifInterface(uri.path ?: return bitmap)
                }

                val orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL
                )

                when (orientation) {
                    ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(bitmap, 90f)
                    ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(bitmap, 180f)
                    ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(bitmap, 270f)
                    ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> flipImage(bitmap, true, false)
                    ExifInterface.ORIENTATION_FLIP_VERTICAL -> flipImage(bitmap, false, true)
                    ExifInterface.ORIENTATION_TRANSPOSE -> {
                        rotateImage(bitmap, 90f).let { flipImage(it, true, false) }
                    }
                    ExifInterface.ORIENTATION_TRANSVERSE -> {
                        rotateImage(bitmap, 90f).let { flipImage(it, false, true) }
                    }
                    else -> bitmap
                }
            } ?: bitmap
        } catch (e: IOException) {
            e.printStackTrace()
            bitmap
        }
    }

    /**
     * 旋转图片
     */
    private fun rotateImage(source: Bitmap, angle: Float): Bitmap {
        val matrix = Matrix()
        matrix.postRotate(angle)
        return Bitmap.createBitmap(
            source, 0, 0, source.width, source.height, matrix, true
        )
    }

    /**
     * 翻转图片
     */
    private fun flipImage(source: Bitmap, horizontal: Boolean, vertical: Boolean): Bitmap {
        val matrix = Matrix()
        matrix.preScale(if (horizontal) -1f else 1f, if (vertical) -1f else 1f)
        return Bitmap.createBitmap(
            source, 0, 0, source.width, source.height, matrix, true
        )
    }

    /**
     * 获取文件大小(KB)
     */
    fun getFileSizeKb(file: File): Long {
        return if (file.exists() && file.isFile) {
            file.length() / 1024
        } else {
            0
        }
    }
}
